package cn.stylefeng.roses.kernel.license;

import cn.hutool.core.codec.Base64;
import cn.hutool.core.util.CharsetUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.RSA;
import cn.stylefeng.roses.kernel.license.api.LicenseApi;
import cn.stylefeng.roses.kernel.license.api.exception.LicenseException;
import cn.stylefeng.roses.kernel.license.api.exception.enums.LicenseExceptionEnum;
import cn.stylefeng.roses.kernel.license.api.pojo.SecretDTO;
import cn.stylefeng.roses.kernel.license.api.util.MacAddressUtil;
import com.alibaba.fastjson.JSON;
import org.springframework.stereotype.Component;

/**
 * RSA方式生成证书的过程
 *
 * @author fengshuonan
 * @date 2021/7/8 13:54
 */
@Component
public class RSALicenseService implements LicenseApi {

    @Override
    public SecretDTO createSecret() {

        SecretDTO secretDTO = new SecretDTO();

        // 获得私钥
        RSA rsa = new RSA();
        String privateKeyBase64 = rsa.getPrivateKeyBase64();
        secretDTO.setPrivateSecret(privateKeyBase64);

        // 获得公钥
        String publicKeyBase64 = rsa.getPublicKeyBase64();
        secretDTO.setPublicSecret(publicKeyBase64);

        // 32字节256位
        byte[] bytes = RandomUtil.randomBytes(32);
        String encode = Base64.encode(bytes);
        secretDTO.setAesSecret(encode);

        return secretDTO;
    }

    @Override
    public String createLicenseStr(SecretDTO secretDTO, String content) {

        // RSA算法，公钥加密
        RSA rsa = new RSA(secretDTO.getPrivateSecret(), secretDTO.getPublicSecret());

        // 获取加密后的字符串
        return rsa.encryptBase64(content, CharsetUtil.CHARSET_UTF_8, KeyType.PublicKey);
    }

    @Override
    public boolean validateLicenseStr(SecretDTO secretDTO, String license) {
        // RSA解密，校验license的正确性
        RSA rsa = new RSA(secretDTO.getPrivateSecret(), secretDTO.getPublicSecret());
        try {
            rsa.decrypt(license, KeyType.PrivateKey);
            return true;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public String decryptLicense(SecretDTO secretDTO, String license) {
        RSA rsa = new RSA(secretDTO.getPrivateSecret(), secretDTO.getPublicSecret());
        try {
            byte[] bytes = rsa.decrypt(license, KeyType.PrivateKey);
            return StrUtil.str(bytes, CharsetUtil.CHARSET_UTF_8);
        } catch (Exception e) {
            throw new LicenseException(LicenseExceptionEnum.DECRYPT_LICENSE_ERROR);
        }
    }

    public static void main(String[] args) throws Exception {
        RSALicenseService rsaLicenseService = new RSALicenseService();
        SecretDTO secret = rsaLicenseService.createSecret();

        System.out.println(secret.getPrivateSecret());
        System.out.println();
        System.out.println(secret.getPublicSecret());

        String licenseStr = rsaLicenseService.createLicenseStr(secret, JSON.toJSONString(MacAddressUtil.getMacList()));
        System.out.println(licenseStr);
    }

}
